﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

//锁定解锁状态分支
void MainWindow::Dlbox_Btn_Lock_Or_Unlock(int EnabledStu)
{
    switch(EnabledStu) {
    case DISP_BTN_LOCK_ALL:{
        ui->btn_read_dlbox->setEnabled(false);
        ui->btn_mtsn_read_dlbox->setEnabled(false);
        ui->btn_write_dlbox->setEnabled(false);
        ui->btn_mtsn_write_dlbox->setEnabled(false);
        ui->cbx_write_dlbox->setEnabled(false);
        ui->cbx_mtsn_write_dlbox->setEnabled(false);
        AutoUpgFile->setEnabled(false);
        //
        ui->cbx_write_dlbox->setCheckState(Qt::Unchecked);
        ui->cbx_mtsn_write_dlbox->setCheckState(Qt::Unchecked);
        break;
    }
    case DISP_BTN_UNLOCK_ALL:
    case DISP_BTN_LOCK_RES:{
        //
        ui->btn_read_dlbox->setEnabled(true);
        ui->btn_mtsn_read_dlbox->setEnabled(true);
        ui->btn_write_dlbox->setEnabled(false);
        ui->btn_mtsn_write_dlbox->setEnabled(false);
        ui->cbx_write_dlbox->setEnabled(true);
        ui->cbx_mtsn_write_dlbox->setEnabled(true);
        AutoUpgFile->setEnabled(false);
        //
        ui->cbx_write_dlbox->setCheckState(Qt::Unchecked);
        ui->cbx_mtsn_write_dlbox->setCheckState(Qt::Unchecked);
        break;
    }
    }
}

void MainWindow::on_cbx_mtsn_write_dlbox_clicked()
{
    bool CbxStu = ui->cbx_mtsn_write_dlbox->isChecked();
    ui->btn_mtsn_write_dlbox->setEnabled(CbxStu);
}
void MainWindow::on_cbx_write_dlbox_clicked()
{
    bool CbxStu = ui->cbx_write_dlbox->isChecked();
    ui->btn_write_dlbox->setEnabled(CbxStu);
}

// 连接按钮
void MainWindow::on_btn_link_dlbox_clicked()
{
    if(LangureStu == 1)
    {
        LangureStr = "Connect";
    }
    else
    {
        LangureStr = "连  接";
    }

    ui->btn_link_dlbox->setEnabled(false);
    ui->cbx_port_dlbox->setEnabled(false);
    if(ui->btn_link_dlbox->text() == LangureStr)
    {
        ConnectStu_dlbox = 1;
        // 下拉菜单控件失能
        LangureStr_Init_Btn_Unlink(ui->btn_link_dlbox);
        CPortName_dlbox = ui->cbx_port_dlbox->currentText();
        if(!CPortName_dlbox.isEmpty())
        {
            QString PortName = CPortName_dlbox.split(":").at(0);
            if(!InitSerial_Dlbox(Port_dlbox, PortName))
            {
                // 打印出错提示
                if(LangureStu == 1)
                {
                    LangureStr = "Unable to open serial port";
                }
                else
                {
                    LangureStr = "无法打开串口";
                }
                InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_WARNNING);
                LangureStr_Init_Btn_Link(ui->btn_link_dlbox);
                ui->cbx_port_dlbox->setEnabled(true);
                ui->btn_link_dlbox->setEnabled(true);
                return;
            }
            LangureStr_Init_Testing(ui->te_prin_dlbox);
            if(DlboxSerial_LinkCmd_Link())// 115200 N-8-1
            {
                // 打印连接成功提示
                if(LangureStu == 1)
                {
                    LangureStr = "Device connected\n\tDevice SN:"+ RespSN_dlbox + "\n\tDevice Version:"+ RespVers_dlbox;
                }
                else
                {
                    LangureStr = "设备已连接\n\t设备SN号:"+ RespSN_dlbox + "\n\t设备版本 :"+ RespVers_dlbox;
                }
                InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_NORMAL);
                SyncTimer_dlbox->start(5000);
                Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_UNLOCK_ALL);
            }
            else
            {
                LangureStr_Init_Btn_Unlink(ui->btn_link_dlbox);
                on_btn_link_dlbox_clicked();
                LangureStr_Init_LinkFailed(ui->te_prin_dlbox);
                return;
            }
        }
        else
        {
            if(ConnectStu_dlbox == 1)
            {
                LangureStr_Init_Btn_Unlink(ui->btn_link_dlbox);
                on_btn_link_dlbox_clicked();
                return;
            }
            else
            {
                LangureStr_Init_Btn_Link(ui->btn_link_dlbox);
            }
        }
    }
    else
    {
		CPortName_dlbox.clear();
        if(SyncTimer_dlbox->isActive())
            SyncTimer_dlbox->stop();
        if(WaitTimer_dlbox->isActive())
            WaitTimer_dlbox->stop();
        Port_dlbox->clear();
        Port_dlbox->close();

        RespStu_dlbox = USB_PAGE_NULL;
        LangureStr_Init_Btn_Link(ui->btn_link_dlbox);
        LangureStr_Init_Unlink();
        if(ConnectStu_dlbox)
        {
            LangureStr_Init_Disconnected();
            InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            ConnectStu_dlbox = 0;
        }

        // 初始化按钮不可编辑
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    }
    ui->cbx_port_dlbox->setEnabled(true);
    ui->btn_link_dlbox->setEnabled(true);
}

// 读盖板码
void MainWindow::on_btn_mtsn_read_dlbox_clicked()
{
    if(!Check_cbx_model_read_Must_Select(ui->cbx_model_read_dlbox, ui->te_prin_dlbox))
    {
        return;
    }
    bool ActiveStu = SyncTimer_dlbox->isActive();
    if(ActiveStu)
    {
        SyncTimer_dlbox->stop();
    }
    Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    // 发送读盖板码命令
    RespMtsn_dlbox.clear();
    DlboxSerial_LinkCmd_ReadMtsn();
    //  返回的盖板码最少为44
    if(RespMtsn_dlbox.size() >= 44)
    {
        RespMtsn_dlbox.replace('\0',' ');
        // 若选择11系列及以下机型，则只有一个盖板码。 12系列及以上有两个盖板码。
        if(ModelStu_dlbox < Model_12)
        {
            // 盖板码-TP-IC
            if(LangureStu == 1)
            {
                LangureStr = tr("MtSN: %1").arg(QString(RespMtsn_dlbox.mid(0, 44)));
            }
            else
            {
                LangureStr = QString("盖板码: %1").arg(QString(RespMtsn_dlbox.mid(0, 44)));
            }
            InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_NORMAL);
        }
        else
        {
            // 盖板码-驱动IC
            if(LangureStu == 1)
            {
                LangureStr = tr("Drive IC MtSN: %1").arg(QString(RespMtsn_dlbox.mid(0, 44)));
            }
            else
            {
                LangureStr = QString("驱动IC盖板码: %1").arg(QString(RespMtsn_dlbox.mid(0, 44)));
            }
            InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            // 盖板码-TP-IC
            if(LangureStu == 1)
            {
                LangureStr = tr("TP-IC MtSN: %1").arg(QString(RespMtsn_dlbox.mid(44, 44)));
            }
            else
            {
                LangureStr = QString("TP-IC 盖板码: %1").arg(QString(RespMtsn_dlbox.mid(44, 44)));
            }
            InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_NORMAL);
        }
    }
    else
    {
        if(LangureStu == 1)
        {
            LangureStr = "failed to read MtSN!";
        }
        else
        {
            LangureStr = "读取盖板码失败!";
        }
        InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_FAILED);
    }

    // 若设备未断开，则恢复按钮组状态及开启同步定时器
    if(ConnectStu_dlbox)
    {
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_RES);
        SyncTimer_dlbox->start(5000);
    }
}
// 写盖板码
void MainWindow::on_btn_mtsn_write_dlbox_clicked()
{
    Dlbox_MtsnCode_Write(false);

    // 若设备未断开，则恢复按钮组状态及开启同步定时器
    if(ConnectStu_dlbox && ConnectStu_dlbox)
    {
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_RES);
        SyncTimer_dlbox->start(5000);
    }
}
void MainWindow::Dlbox_MtsnCode_Write(bool DevStu)
{
    // 检查同步定时器状态
    bool ActiveStu = SyncTimer_dlbox->isActive();
    if(ActiveStu)
    {
        SyncTimer_dlbox->stop();
    }
    // 检查机型是否选择
    if(!Check_cbx_model_read_Must_Select(ui->cbx_model_read_dlbox, ui->te_prin_dlbox))
    {
        return;
    }
    // 锁定按钮组
    Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    LangureStr_Init_BurningCode(ui->te_prin_dlbox);
    // 检查盖板码合法性
    QByteArray MtsnStr = ui->te_mtsn_dlbox->toPlainText().toLatin1();
    if(!App_Check_Legal_MtsnCode(MtsnStr))
    {
        // 警告提示
        InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return;
    }
    // 替换底层数据
    bool RespStu = true;
    if(DevStu)
    {
        // 读取文件内容(16K)
        QString DevFileName = FilePath + "/";
        uint16_t MtsnAddr[3];
        int AddrNum = 0;
        AddrNum = 1;
        switch (ModelStu_dlbox) {
        case Model_XR:    MtsnAddr[0] = MTSN_CODE_ADDR_iXr;  break;
        case Model_X:
        case Model_XSMax:
        {
            MtsnAddr[0] = MTSN_CODE_ADDR_iXs;
            MtsnAddr[1] = MTSN_CODE_ADDR_1_iXs;
            MtsnAddr[2] = MTSN_CODE_ADDR_2_iXs;
            AddrNum = 3;
            break;
        }
        case Model_8:
        case Model_8P:
        case Model_8P_a:  MtsnAddr[0] = MTSN_CODE_ADDR_i8g;  break;
        case Model_11:
        {
            MtsnAddr[0] = MTSN_CODE_ADDR_i11;
            MtsnAddr[1] = MTSN_CODE_ADDR_1_i11;
            AddrNum = 2;
            break;
        }
        case Model_11P:
        {
            MtsnAddr[0] = MTSN_CODE_ADDR_i11P;
            MtsnAddr[1] = MTSN_CODE_ADDR_1_i11P;
            MtsnAddr[2] = MTSN_CODE_ADDR_2_i11P;
            AddrNum = 3;
            break;
        }
        case Model_12:
        {
            MtsnAddr[0] = MTSN_CODE_ADDR_i12;
            MtsnAddr[1] = MTSN_CODE_ADDR_1_i12;
            MtsnAddr[2] = MTSN_CODE_ADDR_2_i12;
            AddrNum = 3;
            break;
        }
        case Model_12PM:  MtsnAddr[0] = MTSN_CODE_ADDR_i12PM;break;
        case Model_13:
        case Model_14:
        case Model_15:
        case Model_16:
		case Model_13P:
		case Model_14P:
		case Model_15P:
		case Model_16P:   MtsnAddr[0] = MTSN_CODE_ADDR_i13;  break;
        default:          MtsnAddr[0] = 0;  AddrNum=0;       break;
        }
        switch (ModelStu_dlbox) {
        case Model_8:
        {
            DevFileName += ROM_FILE_NAME_I8;
            break;
        }
        case Model_8P:
        {
            DevFileName += ROM_FILE_NAME_I8P;
            break;
        }
        case Model_8P_a:
        {
            DevFileName += ROM_FILE_NAME_I8P_A;
            break;
        }
        case Model_X:
        {
            DevFileName += ROM_FILE_NAME_IX;
            break;
        }
        case Model_XR:
        {
            DevFileName += ROM_FILE_NAME_IXR;
            break;
        }
        case Model_XSMax:
        {
            DevFileName += ROM_FILE_NAME_IXSMAX;
            break;
        }
        case Model_11:
        {
            DevFileName += ROM_FILE_NAME_I11;
            break;
        }
        case Model_11P:
        {
            DevFileName += ROM_FILE_NAME_I11P;
            break;
        }
        case Model_12:
        case Model_12PM:
        {
            DevFileName += ROM_FILE_NAME_I12;
            break;
        }
        case Model_13:
        {
            DevFileName += ROM_FILE_NAME_I13;
            break;
        }
		case Model_16:
        case Model_15:
        case Model_14:
        {
            DevFileName += ROM_FILE_NAME_I14;
            break;
        }
        case Model_13P:
        {
            DevFileName += ROM_FILE_NAME_I13Pro;
            break;
        }
		case Model_16P:
        case Model_15P:
        case Model_14P:
        {
            DevFileName += ROM_FILE_NAME_I14Pro;
            break;
        }
        }
        QFile DevFile(DevFileName);
        bool exist = QFile::exists(DevFileName);
        if(!exist)
        {
            LangureStr_Init_FileNonExistent(ui->te_prin_dlbox);
            return ;
        }
        if(16384 != DevFile.size())
        {
            LangureStr_Init_LimitFileSize(ui->te_prin_dlbox);
            return ;
        }
        if(!DevFile.open(QIODevice::ReadOnly))
        {
            LangureStr_Init_FileOpenFail(ui->te_prin_dlbox);
            return ;
        }
        int Length = 0;
        QByteArray BurnData;
        BurnData.clear();
        BurnData.append(DevFile.readAll());
        DevFile.close();
        // 指定地址替换盖板码
        for(int i=0;i<AddrNum;i++)
        {
            BurnData.replace(MtsnAddr[i], 44, MtsnStr);
        }
        Length = BurnData.size();
        // 发送数据
        int iCnt = 0;
        int BurnCnt = 0;
        //
        QByteArray LineData;
        while(0 != Length)
        {
            // 发送写数据命令
            LineData.clear();
            LineData.append(BurnData.mid(iCnt, 1024));
            BurnCnt++;
            if(0 == (Length-1024))
            {
                //
                LangureStr_Init_BurnData_WaitDev(ui->te_prin_dlbox);
            }
            DataCnt_dlbox = BurnCnt;
            if(!DlboxSerial_LinkCmd_BurnData(LineData))
            {
                RespStu = false;
                break;
            }
            if(0 == (Length-1024))
            {
                if(!Wait_TimeOut_to_Wait_Dlbox_Answer())
                {
                    RespStu = false;
                    break;
                }
            }
            if(!ConnectStu_dlbox)
            {
                return ;
            }
            iCnt += 1024;
            Length -= 1024;
        }
    }
    else
    {
        // 写盖板码
        if(!DlboxSerial_LinkCmd_BurnMtsn(MtsnStr))
        {
            RespStu = false;
        }
    }
    if(false == RespStu)
    {
       LangureStr_Init_BurnCode_Failed(ui->te_prin_dlbox);
    }
    else
    {
        LangureStr_Init_BurnCode_Succeed(ui->te_prin_dlbox);
    }

    // 若设备未断开，则恢复按钮组状态及开启同步定时器
    if(ConnectStu_dlbox)
    {
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_RES);
        SyncTimer_dlbox->start(5000);
    }
}
// 读数据
void MainWindow::on_btn_read_dlbox_clicked()
{
    // 检查机型是否选择
    if(!Check_cbx_model_read_Must_Select(ui->cbx_model_read_dlbox, ui->te_prin_dlbox))
    {
        return;
    }
    // 检查同步定时器状态
    bool ActiveStu = SyncTimer_dlbox->isActive();
    if(ActiveStu)
    {
        SyncTimer_dlbox->stop();
    }
    // 显示接收区清空内容
    hexEdit_dlbox->clear();

    // 文件名
    QString ReadFileName = ui->te_file_write_dlbox->toPlainText();
    ReadFileName = ReadFileName.replace("file:///","");
    // 检查文件名是否合法
    if(!App_Check_Legal_FilePath(ReadFileName, 1))
    {
        InsertText(ui->te_prin_dlbox, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return ;
    }
    App_Write_FilePath_CfgFile("OpenDir/Dir", BurnFileName);
    //
    QFile ReadFile(ReadFileName);
    if(!ReadFile.open(QIODevice::WriteOnly))
    {
        LangureStr_Init_FileOpenFail(ui->te_prin_dlbox);
        return;
    }
    // 锁定按钮组
    Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    // 读数据
    qint64 Length = 0;
    int ReadCnt = 0;
    QByteArray ReadBuff;
    LangureStr_Init_ReadingData(ui->te_prin_dlbox);
    bool RespStu = true;
    while(1){
        ReadBuff.clear();
        // 发送读数据命令
        ReadCnt++;
        RespData_dlbox.clear();
        DataCnt_dlbox = ReadCnt;
        if(!DlboxSerial_LinkCmd_ReadData())
        {
            RespStu = false;
            break;
        }
        if(!ConnectStu_dlbox)
        {
            ReadFile.close();
            return;
        }
        Length = 0;

        if(RespData_dlbox.size() >= 1024)
        {
            ReadBuff.append(RespData_dlbox.mid(0, 1024));
            ReadFile.write(ReadBuff, 1024);
            hexEdit_dlbox->append(ReadBuff);
        }
        if(16 == ReadCnt)
        {
            break;
        }
    }
    //
    ReadFile.close();
    if(false == RespStu)
    {
        LangureStr_Init_ReadData_Failed(ui->te_prin_dlbox);
    }
    else
    {
        LangureStr_Init_ReadData_Succeed(ui->te_prin_dlbox);
    }
    // 若设备未断开，则恢复按钮组状态及开启同步定时器
    if(ConnectStu_dlbox)
    {
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_RES);
        SyncTimer_dlbox->start(5000);
    }
}
// 写数据
void MainWindow::on_btn_write_dlbox_clicked()
{
    if(!Check_cbx_model_read_Must_Select(ui->cbx_model_read_dlbox, ui->te_prin_dlbox))
    {
        return;
    }
    bool ActiveStu = SyncTimer_dlbox->isActive();
    if(ActiveStu)
    {
        SyncTimer_dlbox->stop();
    }
    //
    LangureStr_Init_BurningData(ui->te_prin_dlbox);
    // 写数据
    QString BurnFileName = ui->te_file_write_dlbox->toPlainText();
    BurnFileName = BurnFileName.replace("file:///","");
    QFile BurnFile(BurnFileName);
    if(BurnFile.size() != 16384)
    {
        LangureStr_Init_LimitFileSize(ui->te_prin_dlbox);
        return;
    }
    if(!BurnFile.open(QIODevice::ReadOnly))
    {
        LangureStr_Init_FileOpenFail(ui->te_prin_dlbox);
        return;
    }
    // 锁定按钮组
    Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    char LineBuff[1024];
    qint64 Length = 0;
    int BurnCnt = 0;
    QByteArray BurnBuff;
    bool RespStu = true;
    //
    while(!BurnFile.atEnd()){
        Length = BurnFile.read(LineBuff, 1024);
        BurnBuff.clear();
        for(int i=0;i<Length;i++)
        {
            BurnBuff.append(LineBuff[i]);
        }
        int WaitTime = 0;
        // 发送写数据命令
        BurnCnt++;
        if(16 == BurnCnt)
        {
            LangureStr_Init_BurnData_WaitDev(ui->te_prin_dlbox);
        }
        WaitTime = 0;

        DataCnt_dlbox = BurnCnt;
        if(!DlboxSerial_LinkCmd_BurnData(BurnBuff))
        {
            RespStu = false;
            break;
        }
        if(16 == BurnCnt)
        {
            if(!Wait_TimeOut_to_Wait_Dlbox_Answer())
            {
                RespStu = false;
                break;
            }
        }
        if(!ConnectStu_dlbox)
        {
            BurnFile.close();
            return ;
        }
        if(16 == BurnCnt)
        {
            break;
        }
    }
    BurnFile.close();

    if(false == RespStu)
    {
        LangureStr_Init_BurnData_Failed(ui->te_prin_dlbox);
    }
    else
    {
        LangureStr_Init_BurnData_Succeed(ui->te_prin_dlbox);
    }
    // 若设备未断开，则恢复按钮组状态及开启同步定时器
    if(ConnectStu_dlbox)
    {
        Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_RES);
        SyncTimer_dlbox->start(5000);
    }
}

// 选择文件
void MainWindow::on_btn_file_write_dlbox_clicked()
{
    bool ActiveStu = SyncTimer_dlbox->isActive();
    if(ActiveStu)
    {
        SyncTimer_dlbox->stop();
    }
    App_ChooseFile_SavePath(ui->te_file_write_dlbox, "FILE_DLBOX");
    // 若设备未断开，则开启同步定时器
    if(ActiveStu)
    {
        SyncTimer_dlbox->start(5000);
    }
}

void MainWindow::on_cbx_model_read_dlbox_activated(int index)
{
    ModelStu_dlbox = index;

    switch(ModelStu_dlbox){
    case Model_15P:
    case Model_12:
    case Model_12PM:
    case Model_13:
    case Model_14:
    case Model_15:
    case Model_13P:
    case Model_14P:
    case Model_16:
    case Model_16P:
    {
        //隐藏
        if(LangureStu == 1)
        {
            LangureStr = "Warm prompt: 12-16 display glass IC has a limit on the number of times to write (generally 1-5 times). After the number of times is written, no data can be written. Please be careful!";
        }
        else
        {
            LangureStr = "温馨提示：12-16的显示玻璃ic有写入次数的限制(一般1-5次)，次数写完后就写不进数据了，请谨慎操作！";
        }
        InsertText(ui->te_prin_dlbox, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        break;
    }
    default:
    {
        //显示
        break;
    }
    }
}
